package org.dtrd.modules.record.service;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dtrd.config.system.Constant;
import org.dtrd.modules.record.entity.bean.CheckinRecord;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 打卡记录Service基类
 *
 * @author 萧
 * @date:2021-08-22 9:19 下午
 **/
public interface IRecordService<T> extends IService<T> {

    /**
     * 转换并校验保存记录
     *
     * @param checkinRecord
     * @return
     */
    default T saveRecord(CheckinRecord checkinRecord) {
        T t = transformRecord(checkinRecord);
        if (checkRecord(checkinRecord)) {
            saveOrUpdate(t);
        }
        return t;
    }

    default CheckinRecord selectRecordById(Integer dataId) {
        T t = getBaseMapper().selectById(dataId);
        return transformPO(t);
    }


    default Date parseStringAsDate(String recordTime) {
        return DateUtil.parse(recordTime, DatePattern.NORM_DATE_PATTERN);
    }

    default Date parseStringAsDateTime(String recordTime) {
        return DateUtil.parse(recordTime, DatePattern.NORM_DATETIME_PATTERN);
    }

    /**
     * 校验数据记录，校验通过执行保存
     * subType为0直接校验通过
     *
     * @param checkinRecord
     * @return
     */
    default boolean checkRecord(CheckinRecord checkinRecord) {
        return selectBySubType(checkinRecord.getPatientId(), checkinRecord.getRecordDate(), checkinRecord.getSubType()) == null;
    }

    T transformRecord(CheckinRecord checkinRecord);

    CheckinRecord transformPO(T t);

    LambdaQueryWrapper<T> generateSelectRecordByDateQuery(Integer patientId,String date, Integer subType);

    default T selectBySubType(Integer patientId,String date, Integer subType) {
        LambdaQueryWrapper<T> query = generateSelectRecordByDateQuery(patientId,date,subType);
        List<T> list = getBaseMapper().selectList(query);
        return Optional.ofNullable(list).map(l -> {
            if (l.isEmpty()) {
                return null;
            }
            return l.get(0);
        }).orElse(null);
    }

    default Integer judgeRecordStatus(Float value, Float limitLow, Float limitUp) {
        if (value != null && limitLow != null && limitUp != null) {
            if (value < limitLow) {
                return Constant.RecordStatus.LOWER.getType();
            } else if (value > limitUp) {
                return Constant.RecordStatus.HIGHER.getType();
            }
        }
        return Constant.RecordStatus.NORMAL.getType();
    }

}
